package com.ld.security.common.tomcat.handler;

import cn.hutool.core.exceptions.ExceptionUtil;
import com.alibaba.fastjson.JSONException;
import com.ld.security.common.core.base.vo.DataVo;
import com.ld.security.common.core.base.vo.ExceptionVo;
import com.ld.security.common.core.exception.ApiException;
import com.ld.security.common.core.exception.SuperException;
import com.ld.security.common.core.util.JsonUtil;
import com.ld.security.common.core.util.TemplateUtil;
import com.ld.security.common.tomcat.config.AppInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.mail.internet.MimeMessage;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.concurrent.CompletableFuture;

@ControllerAdvice

public class BaseExceptionHandler {


	@Autowired
	JavaMailSender jms;


	@Autowired
	private AppInfo appInfo;


	@Value("${spring.mail.username}")
	private String from;


	public void sendMail(ExceptionVo vo){

		CompletableFuture.runAsync(() -> {
			try {
				HashMap params = 	new HashMap<>();
				params.put("info",appInfo);
				params.put("ex",vo);
				//	params.put("url",SessionUtil.getAppUrl());

				final MimeMessage mimeMessage = jms.createMimeMessage();

				String html = TemplateUtil.renderTemplate("templates/errorEmail.html.vm",params);

				MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
				helper.setFrom(from);
				helper.setTo(appInfo.getEmail());
				helper.setSubject(appInfo.getTitle());
				helper.setText(html, true);
				jms.send(mimeMessage);
			}catch (Exception e){
				e.printStackTrace();
			}

		});

	}



	
    @ExceptionHandler(value = {MethodArgumentNotValidException.class})
    @ResponseBody
    public DataVo<ExceptionVo> MethodArgumentNotValidException(final MethodArgumentNotValidException ex, final HttpServletRequest req, final HttpServletResponse resp) {

		HashMap<String,Object> map =new HashMap<>();
    	ex.getBindingResult().getFieldErrors().forEach(val -> {
    		map.put(val.getField(),val.getDefaultMessage());
    	});
		ExceptionVo vo = new ExceptionVo();
		vo.setLabel("参数校验异常抛出");
		vo.setContent(JsonUtil.toJson(map));

		vo.setExType("业务异常");
		DataVo dataVo = DataVo.of(vo);
		dataVo.setMessage("参数校验异常抛出");
		dataVo.setCode(400);
    	return  dataVo;
    }
	
	@ExceptionHandler(value = {ApiException.class})
   @ResponseBody
    public DataVo<ExceptionVo> ApiException  (final ApiException ex, final HttpServletRequest req, final HttpServletResponse resp) {
		ex.printStackTrace();
		String content = ExceptionUtil.stacktraceToString (ex);
		ExceptionVo vo = new ExceptionVo();
		vo.setLabel(ex.getMessage());
		vo.setContent(content);

		vo.setExType("业务异常");
		DataVo dataVo = DataVo.of(vo);
		dataVo.setMessage(ex.getMessage());
		dataVo.setCode(ex.getCode());

    	return dataVo;
    }


	@ExceptionHandler(value = {JSONException.class})
	@ResponseBody
	public DataVo<ExceptionVo> JSONException  (final JSONException ex) {
		ex.printStackTrace();
		String content = ExceptionUtil.stacktraceToString (ex);
		ExceptionVo vo = new ExceptionVo();

		vo.setContent(content);
		vo.setLabel(ex.getMessage());
		vo.setExType("json格式异常");
		DataVo dataVo = DataVo.of(vo);
		dataVo.setMessage("json格式异常");
		dataVo.setCode(400);
		return dataVo;
	}

	@ExceptionHandler(value = {SuperException.class})
	@ResponseBody
	public DataVo<ExceptionVo> SuperException  (final SuperException ex, final HttpServletRequest req, final HttpServletResponse resp) {
		ex.printStackTrace();
		String content = ExceptionUtil.stacktraceToString (ex);
		ExceptionVo vo = new ExceptionVo();

		vo.setContent(content);
		vo.setLabel(ex.getMessage());
		vo.setExType("业务异常");
		DataVo dataVo = DataVo.of(vo);
		dataVo.setMessage("业务异常");
		dataVo.setCode(400);
		return dataVo;
	}

	@ExceptionHandler(value = {Exception.class})
	@ResponseBody
	public DataVo<ExceptionVo> Exception  (final Exception ex, final HttpServletRequest req, final HttpServletResponse resp) {
		ex.printStackTrace();
		String content = ExceptionUtil.stacktraceToString (ex);
		ExceptionVo vo = new ExceptionVo();

		vo.setContent(content);

		vo.setExType("系统异常");
		DataVo dataVo = DataVo.of(vo);
		dataVo.setMessage("系统异常");
		dataVo.setCode(400);

		this.sendMail(vo);
		return dataVo;
	}

}
